﻿using HCQ2_Model.ViewModel.WebAPI;
using HCQ2WebAPI_Logic.BaseAPIController;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using HCQ2_Model.VRDD.OutputDto._211217;
using HCQ2_Model.VRDD.InputDto._211217;
using HCQ2WebAPI_Logic.Model;
using HCQ2_Common.Constant;
using HCQ2_Model.VR;
using HCQ2_Common;
using HCQ2_Model;
using System.IO;
using System.Net.Http;
using HCQ2_Model.VRQDMeta.InputDto._20220112;
using HCQ2_Model.VRQDMeta.OutputDto._20220112;
using HCQ2_Model.ViewModel;
using HCQ2_Model.VRDD.InputDto._210908;
using HCQ2_Model.VRDD.InputDto._20220314;
using HCQ2_Model.APIBase;
using HCQ2_Model.VRDD.OutputDto._20220314;
using System.Globalization;
using HCQ2_Model.VRQDMeta.InputDto._20220418;
using System.Web;
using HCQ2_Model.VRQDMeta.OutputDto._20220418;
using HCQ2WebAPI_Logic.Filters;
using HCQ2_Model.VRDD.OutputDto._20220620;
using HCQ2_Model.VRDD.InputDto._20220620;
using HCQ2_Model.Pay;
using HCQ2_Model.VRDD.InputDto._20220625;
using HCQ2UI_Helper.Session;
using HCQ2_Model.VRDD.OutputDto._20220625;
using HCQ2_Model.VRDD.OutputDto._20220704;
using HCQ2_Model.VRDD.InputDto._20220704;

namespace HCQ2WebAPI_Logic.DDController
{
    /// <summary>
    ///  楼宇相关api控制器
    /// </summary>
    public class VRQiDianController : BaseWeiXinApiLogic
    {
        #region 1.0 ✔保存入住信息 + WebApiResultJsonModel SaveHouseOwner(InputSaveHouse param)
        /// <summary>
        ///  1.0 ✔保存入住信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、20220606需求 id=【2.2】<br/>
        /// 2、20220614需求 id=【1.1】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<OutputSaveHouse> SaveHouseOwner(InputSaveHouse param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<OutputSaveHouse>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            if (string.IsNullOrEmpty(param.folderPath) && string.IsNullOrEmpty(param.fileCode))
                return ApiResultJsonModel<OutputSaveHouse>.RedirectWebApi(WebResultCode.Exception, "folderPath、fileCode不能同时为空！", null);
            OutputSaveHouse result = operateContext.bllSession.T_VRStayUserLog.GetBuildData(param);
            if (result == null)
                return ApiResultJsonModel<OutputSaveHouse>.RedirectWebApi(WebResultCode.Exception, "当前参数查无可住楼房！", null);
            //判断是否更新搬出时间
            var logs = operateContext.bllSession.T_VRStayUserLog.FindSingle(s => s.file_id == result.fileID && s.user_code.Equals(param.userID) && s.out_date == null);
            int stayNum = 0;//新增入住人数
            if (logs != null)
            {
                stayNum -= 1;
                operateContext.bllSession.T_VRStayUserLog.Modify(new T_VRStayUserLog { out_date = DateTime.Now }, s => s.log_id == logs.log_id, "out_date");
            }
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == result.fileID);
            var log = new T_VRStayUserLog
            {
                user_code = param.userID,
                file_id = result.fileID,
                file_name = result.filename,
                file_code = result.fileCode,
                stayType = 0,//虚拟入住
                in_date = DateTime.Now
            };
            //实际入住
            if (!string.IsNullOrEmpty(param.fileCode) && file != null && string.IsNullOrEmpty(file.issue_name))
                log.stayType = 1;
            int mark = operateContext.bllSession.T_VRStayUserLog.Add(log);
            if (mark <= 0)
                return ApiResultJsonModel<OutputSaveHouse>.RedirectWebApi(WebResultCode.Exception, "添加入住失败！", null);
            stayNum += 1;
            //更新入住人信息【实际入住才更新】
            if (!string.IsNullOrEmpty(param.fileCode) && file != null && string.IsNullOrEmpty(file.issue_name))
                operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { issue_name = param.userID }, s => s.file_id == result.fileID, "issue_name");
            //目录【更新商品--目录入住人数】
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == result.folderID);
            stayNum = stayNum < 0 ? 0 : stayNum;
            operateContext.bllSession.T_DocumentFolder.Modify(new T_DocumentFolder { stayNum = folder.stayNum + stayNum }, s => s.folder_id == result.folderID, "stayNum");
            return ApiResultJsonModel<OutputSaveHouse>.RedirectWebApi(WebResultCode.Ok, "添加入住成功！", result);
        }
        #endregion

        #region 1.1 ✔获取房屋信息 + WebApiResultJsonModel GetHouseInfo(InputHouseInfo param)
        /// <summary>
        ///  1.1 ✔获取房屋信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<OutputHouseInfo> GetHouseInfo(InputHouseInfo param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<OutputHouseInfo>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = 0;
            if (!string.IsNullOrEmpty(param.userID))
                user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userID);
            var obj = operateContext.bllSession.T_VRStayUserLog.GetHouseInfo(param, user_id);
            return ApiResultJsonModel<OutputHouseInfo>.RedirectWebApi(WebResultCode.Ok, "获取房屋信息获取成功！", obj);
        }
        #endregion

        #region 1.2 ✔获取用户的入住信息 + WebApiResultJsonModel GetUserHouseInfo(BaseVRAPI param)
        /// <summary>
        ///  1.2 ✔获取用户的入住信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<OutputUserHouseInfo> GetUserHouseInfo(BaseVRAPI param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<OutputUserHouseInfo>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var obj = operateContext.bllSession.T_VRStayUserLog.GetUserHouseInfo(param);
            return ApiResultJsonModel<OutputUserHouseInfo>.RedirectWebApi(WebResultCode.Ok, "获取用户的入住信息成功！", obj);
        }
        #endregion

        #region 1.3 ✔保存用户搬出住宅 + WebApiResultJsonModel SaveUserHouseOut(InputUserHouseOut param)
        /// <summary>
        ///  1.3 ✔保存用户搬出住宅
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、20220614需求 id=【1.2】<br/>
        /// 2、20220626 禅道需求348 搬出时清空vUrl字段
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel SaveUserHouseOut(InputUserHouseOut param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID);
            if (file == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "当前住宅不存在！", null);
            var log = operateContext.bllSession.T_VRStayUserLog.FindSingle(s => s.file_id == param.fileID && s.user_code.Equals(param.userID) && s.out_date == null);
            int stayNum = 0;//搬出入住人数 
            //2.1、更新搬出时间
            if (log != null)
            {
                stayNum = 1;
                operateContext.bllSession.T_VRStayUserLog.Modify(new T_VRStayUserLog { out_date = DateTime.Now }, s => s.log_id == log.log_id, "out_date");
            }
            //2.2、清空 注入用户、别名
            if (file.issue_name.Equals(param.userID))
                operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { issue_name = "", alias_name = "", vUrl = "" }, s => s.file_id == param.fileID, "issue_name", "alias_name", "vUrl");
            //2.3、更新商品对应目录入住人数
            var folder = operateContext.bllSession.T_DocumentFolder.GetFolderByFileId(param.fileID);
            stayNum = folder.stayNum - stayNum;
            stayNum = stayNum < 0 ? 0 : stayNum;
            operateContext.bllSession.T_DocumentFolder.Modify(new T_DocumentFolder { stayNum = stayNum }, s => s.folder_id == folder.folder_id, "stayNum");
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "用户搬出住宅成功！", null);
        }
        #endregion

        #region 1.4 ✔保存用户默认住宅 + WebApiResultJsonModel SaveUserHouseDefault(InputUserHouseOut param)
        /// <summary>
        ///  1.4 ✔保存用户默认住宅
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、20220614需求 id=【1.4】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel SaveUserHouseDefault(InputUserHouseOut param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID);
            if (file == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "当前住宅不存在！", null);
            //2.1、更新用户全部入住为非默认住宅
            operateContext.bllSession.T_VRStayUserLog.Modify(new T_VRStayUserLog { stayDefault = 0 }, s => s.user_code.Equals(param.userID), "stayDefault");
            //2.2、判断用户此商品有无未搬出记录
            var log = operateContext.bllSession.T_VRStayUserLog.FindSingle(s => s.user_code.Equals(param.userID) && s.file_id == param.fileID && s.out_date == null);
            if (null != log)
                operateContext.bllSession.T_VRStayUserLog.Modify(new T_VRStayUserLog { stayDefault = 1 }, s => s.log_id == log.log_id, "stayDefault");
            else
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户在此住宅没有未搬出的记录！", null);
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "用户默认住宅设置成功！", null);
        }
        #endregion

        #region 1.5 ✔获取用户住宅列表 + WebApiResultJsonModel GetUserHouseList(InputUserHouse param)
        /// <summary>
        ///  1.5 ✔获取用户住宅列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、20220614需求 id=【1.5】<br/>
        /// 2、20220625 禅道需求 347
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<BasePage<OutputUserHouse>> GetUserHouseList(InputUserHouse param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<BasePage<OutputUserHouse>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var result = operateContext.bllSession.T_VRStayUserLog.GetUserHouseList(param);
            return ApiResultJsonModel<BasePage<OutputUserHouse>>.RedirectWebApi(WebResultCode.Ok, "获取用户住宅列表成功！", result);
        }
        #endregion

        //*******************************************20211223需求文档******************************************
        #region 2.1 ✔添加事件 + async Task<WebApiResultJsonModel<int>> AddMemo()
        /// <summary>
        ///  2.1 ✔添加事件
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// 提交方式：Form表单提交<br/>
        /// 表单参数：<br/>
        /// userID【必填】： string 用户编码<br/>
        /// memoDate【非必填】string 事件日期 格式：yyyy-MM-dd<br/>
        /// Memo【非必填】：string 内容<br/>
        /// Image【非必填】：file 图片<br/>
        /// Audio【非必填】： file 音频<br/>
        /// Video【非必填】： file 视频<br/>
        /// 注意：内容、图片、音频，视频至少需要有一个不为空<br/>
        /// </remarks>
        [HttpPost]
        public async Task<WebApiResultJsonModel<int?>> AddMemo()
        {
            string userid = RequestHelper.GetStrByName("userID"),
                memo = RequestHelper.GetStrByName("Memo"),
                memoDate = RequestHelper.GetStrByName("memoDate");
            if (string.IsNullOrEmpty(memoDate))
                memoDate = DateTime.Now.ToString("yyyy-MM-dd");
            //DateTime devent = DateTime.Now;
            //if (!string.IsNullOrEmpty(memoDate))
            //{
            //    try {
            //        devent = DateTime.ParseExact(memoDate, "yyyyMMddHHmmss", CultureInfo.CurrentCulture, DateTimeStyles.None);
            //    }
            //    catch
            //    {
            //        throw new Exception("事件日期【memoDate】格式有误，请使用：yyyyMMddHHmmss格式！");   
            //    }
            //}
            T_User user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(userid));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "用户id信息异常~", null);
            //图片、音频、视频上传路径
            string pathServer = $"/uploadFile/DDFile/" + userid + "/" + DateTime.Now.ToString("yyyyMMdd") + "/memo/";
            string uploadPath = request.MapPath(request.ApplicationPath + pathServer);
            if (!Directory.Exists(uploadPath))
                Directory.CreateDirectory(uploadPath);
            CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(uploadPath);
            //定义上传文件名称【图片】
            List<string> upFileNames = new List<string>();//文件存放路径
                                                          //定义上传文件名称【音频】
            List<string> upAudioFileNames = new List<string>();//文件存放路径
            //定义上传文件名称【视频】
            List<string> upVideoFileNames = new List<string>();//文件存放路径
            try
            {
                //上传附件
                await Request.Content.ReadAsMultipartAsync(provider);
                //获取原始文件名称
                foreach (MultipartFileData file in provider.FileData)
                {
                    string fileTypeName = file.Headers.ContentDisposition.Name.Trim('"');
                    //图片
                    if (fileTypeName.Equals("Image"))
                        upFileNames.Add(Path.GetFileName(file.LocalFileName));
                    //音频
                    else if (fileTypeName.Equals("Audio"))
                        upAudioFileNames.Add(Path.GetFileName(file.LocalFileName));
                    //视频
                    else if (fileTypeName.Equals("Video"))
                        upVideoFileNames.Add(Path.GetFileName(file.LocalFileName));
                }
                //判断内容、图片、音频，视频至少需要有一个不为空
                if (string.IsNullOrEmpty(memo) && (upFileNames == null || upFileNames.Count <= 0) && (upVideoFileNames == null || upVideoFileNames.Count <= 0) && (upAudioFileNames == null || upAudioFileNames.Count <= 0))
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "提示：内容、图片、音频，视频至少需要有一个不为空！", null);
                DateTime dt = DateTime.Now;
                string imageUrl = (upFileNames != null && upFileNames.Count > 0) ? $"~{pathServer}{upFileNames[0]}" : "",
                    audioUrl = (upAudioFileNames != null && upAudioFileNames.Count > 0) ? $"~{pathServer}{upAudioFileNames[0]}" : "",
                    videoUrl = (upVideoFileNames != null && upVideoFileNames.Count > 0) ? $"~{pathServer}{upVideoFileNames[0]}" : "";
                //是否需要清空图片
                if (!string.IsNullOrEmpty(imageUrl) && imageUrl.IndexOf(".") < 0)
                {
                    imageUrl = "";
                    File.Delete(uploadPath + upFileNames[0]);
                }
                //是否需要清空音频
                if (!string.IsNullOrEmpty(audioUrl) && audioUrl.IndexOf(".") < 0)
                {
                    audioUrl = "";
                    File.Delete(uploadPath + upAudioFileNames[0]);
                }
                //是否需要清空视频
                if (!string.IsNullOrEmpty(videoUrl) && videoUrl.IndexOf(".") < 0)
                {
                    videoUrl = "";
                    File.Delete(uploadPath + upVideoFileNames[0]);
                }
                T_VRDDEvent et = new T_VRDDEvent
                {
                    userid = userid,
                    memo = memo,
                    imageUrl = imageUrl,
                    audioUrl = audioUrl,
                    videoUrl = videoUrl,
                    createName = user.user_name,
                    createDate = dt
                };
                int mark = operateContext.bllSession.T_VRDDEvent.Add(et);
                if (mark <= 0)
                {
                    if (upFileNames != null && upFileNames.Count > 0)
                        File.Delete(uploadPath + upFileNames[0]);
                    if (upAudioFileNames != null && upAudioFileNames.Count > 0)
                        File.Delete(uploadPath + upAudioFileNames[0]);
                    if (upVideoFileNames != null && upVideoFileNames.Count > 0)
                        File.Delete(uploadPath + upVideoFileNames[0]);
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "事件保存失败！", null);
                }
                //写入事件提醒表
                int evt = operateContext.bllSession.T_VRDDEventAlert.Add(new T_VRDDEventAlert
                {
                    userid = userid,
                    memoId = et.memoId,
                    memoDate = memoDate,//devent.ToString("yyyy-MM-dd"),
                    remindDate = DateTime.Now.ToString("HH:mm"),
                    indexRemind = false,
                    colorNum = 0,
                    createName = user.user_name,
                    createDate = dt
                });
                if (evt <= 0)
                {
                    //提醒写入失败
                    operateContext.bllSession.T_VRDDEvent.Delete(s => s.memoId == et.memoId);
                    foreach (string item in upFileNames)
                        File.Delete(uploadPath + item);
                    foreach (string item in upAudioFileNames)
                        File.Delete(uploadPath + item);
                    foreach (string item in upVideoFileNames)
                        File.Delete(uploadPath + item);
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Error, "事件保存失败！", null);
                }
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "事件保存成功！", et.memoId);
            }
            catch (Exception ex)
            {
                foreach (string item in upFileNames)
                    File.Delete(uploadPath + item);
                foreach (string item in upAudioFileNames)
                    File.Delete(uploadPath + item);
                foreach (string item in upVideoFileNames)
                    File.Delete(uploadPath + item);
                throw ex;
                //return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Error, "事件保存失败！", null);
            }
        }
        #endregion

        #region 2.2 ✔添加事件提醒 + WebApiResultJsonModel<int?> AddMemoRemind(InputAddMemoRemind param)
        /// <summary>
        ///  2.2 ✔添加事件提醒
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> AddMemoRemind(InputAddMemoRemind param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            T_User user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userID));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "用户id信息异常~", null);
            T_VRDDEventAlert eat = new T_VRDDEventAlert
            {
                userid = param.userID,
                memoId = param.memoID,
                aType = param.Type,
                memoDate = param.Date,
                remindDate = param.Time,
                indexRemind = param.indexRemind,
                colorNum = param.colorNum,
                createName = user.user_name,
                createDate = DateTime.Now,
                updateName = user.user_name,
                updateDate = DateTime.Now
            };
            var o = operateContext.bllSession.T_VRDDEventAlert.FindSingle(s => s.userid.Equals(param.userID) && s.memoId == param.memoID && s.memoDate.Equals(param.Date));
            int mark = 0;
            if (o != null)
                //更新
                mark = operateContext.bllSession.T_VRDDEventAlert.Modify(eat, s => s.memoRemindID == o.memoRemindID, "aType", "remindDate", "indexRemind", "colorNum", "updateName");
            else
                //添加
                mark = operateContext.bllSession.T_VRDDEventAlert.Add(eat);
            if (mark > 0)
            {
                if (!string.IsNullOrEmpty(param.Memo))
                    operateContext.bllSession.T_VRDDEvent.Modify(new T_VRDDEvent { memo = param.Memo }, s => s.memoId == param.memoID, "memo");
            }
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "添加事件提醒成功！", eat.memoRemindID);
        }
        #endregion

        #region 2.3 ✔关闭事件首页提醒 + WebApiResultJsonModel CloseMemoRemind(InputCloseMemoRemind param)
        /// <summary>
        ///  2.3 ✔关闭事件首页提醒
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel CloseMemoRemind(InputCloseMemoRemind param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int mark = operateContext.bllSession.T_VRDDEventAlert.SelectCount(s => s.memoRemindID == param.memoRemindID && s.userid.Equals(param.userID));
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "根据参数后台查无数据！", null);
            operateContext.bllSession.T_VRDDEventAlert.Modify(new T_VRDDEventAlert { indexRemind = false }, s => s.memoRemindID == param.memoRemindID, "indexRemind");
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功关闭首页提醒！", null);
        }
        #endregion

        #region 2.4 ✔删除事件提醒 + WebApiResultJsonModel DeleteMemoRemind(InputCloseMemoRemind param)
        /// <summary>
        ///  2.4 ✔删除事件提醒
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel DeleteMemoRemind(InputCloseMemoRemind param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var o = operateContext.bllSession.T_VRDDEventAlert.FindSingle(s => s.memoRemindID == param.memoRemindID && s.userid.Equals(param.userID));
            if (o == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "根据参数后台查无数据！", null);
            int memoId = o.memoId;
            int mark = operateContext.bllSession.T_VRDDEventAlert.Delete(s => s.memoRemindID == param.memoRemindID && s.userid.Equals(param.userID));
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "删除事件提醒失败！", null);
            //判断此事件下是否还存在提醒记录
            int count = operateContext.bllSession.T_VRDDEventAlert.SelectCount(s => s.memoId == memoId);
            if (count <= 0)
            {
                //不存在则删除事件表
                var f = operateContext.bllSession.T_VRDDEvent.FindSingle(s => s.memoId == memoId && s.userid.Equals(param.userID));
                if (f != null && !string.IsNullOrEmpty(f.imageUrl) && File.Exists(request.MapPath(f.imageUrl)))
                    File.Delete(request.MapPath(f.imageUrl));
                if (f != null && !string.IsNullOrEmpty(f.audioUrl) && File.Exists(request.MapPath(f.audioUrl)))
                    File.Delete(request.MapPath(f.audioUrl));
                if (f != null && !string.IsNullOrEmpty(f.videoUrl) && File.Exists(request.MapPath(f.videoUrl)))
                    File.Delete(request.MapPath(f.videoUrl));
                operateContext.bllSession.T_VRDDEvent.Delete(s => s.memoId == memoId && s.userid.Equals(param.userID));
            }
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功删除事件提醒！", null);
        }
        #endregion

        #region 2.5 ✔按日期删除事件提醒 + WebApiResultJsonModel DeleteMemoRemindByDate(InputDeleteMemoAlert param)
        /// <summary>
        ///  2.5 ✔按日期删除事件提醒
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        ///  提醒：删除请求日期及该日期之后的所有事件提醒数据，如果该事件的所有提醒数据都已删除，则还需删除该事件数据
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel DeleteMemoRemindByDate(InputDeleteMemoAlert param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int mark = operateContext.bllSession.T_VRDDEvent.DeleteMemoRemindByDate(param);
            if (mark > 0)
            {
                mark = operateContext.bllSession.T_VRDDEventAlert.SelectCount(s => s.memoId == param.memoID);
                if (mark <= 0)
                {
                    //删除之前判断有无附件
                    var f = operateContext.bllSession.T_VRDDEvent.FindSingle(s => s.memoId == param.memoID);
                    if (f != null && !string.IsNullOrEmpty(f.imageUrl) && File.Exists(request.MapPath(f.imageUrl)))
                        File.Delete(request.MapPath(f.imageUrl));
                    if (f != null && !string.IsNullOrEmpty(f.audioUrl) && File.Exists(request.MapPath(f.audioUrl)))
                        File.Delete(request.MapPath(f.audioUrl));
                    if (f != null && !string.IsNullOrEmpty(f.videoUrl) && File.Exists(request.MapPath(f.videoUrl)))
                        File.Delete(request.MapPath(f.videoUrl));
                    operateContext.bllSession.T_VRDDEvent.Delete(s => s.memoId == param.memoID);
                }
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "按日期删除事件提醒成功！", null);
            }
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "按日期删除事件提醒失败！", null);
        }
        #endregion

        #region 2.6 ✔删除事件 + WebApiResultJsonModel DeleteMemo(InputDeleteMemo param)
        /// <summary>
        ///  2.6 ✔删除事件
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel DeleteMemo(InputDeleteMemo param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var f = operateContext.bllSession.T_VRDDEvent.FindSingle(s => s.memoId == param.memoID && s.userid.Equals(param.userID));
            if (f != null && !string.IsNullOrEmpty(f.imageUrl) && File.Exists(request.MapPath(f.imageUrl)))
                File.Delete(request.MapPath(f.imageUrl));
            if (f != null && !string.IsNullOrEmpty(f.audioUrl) && File.Exists(request.MapPath(f.audioUrl)))
                File.Delete(request.MapPath(f.audioUrl));
            if (f != null && !string.IsNullOrEmpty(f.videoUrl) && File.Exists(request.MapPath(f.videoUrl)))
                File.Delete(request.MapPath(f.videoUrl));
            int mark = operateContext.bllSession.T_VRDDEvent.Delete(s => s.memoId == param.memoID && s.userid.Equals(param.userID));
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "删除事件失败！", null);
            mark = operateContext.bllSession.T_VRDDEventAlert.Delete(s => s.memoId == param.memoID);
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功删除事件以及提醒！", null);
        }
        #endregion

        #region 2.7 ✔获取事件列表 + WebApiResultJsonModel GetMemoList(InputMemoList param)
        /// <summary>
        ///  2.7 ✔获取事件列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<List<OutputMemoList>> GetMemoList(InputMemoList param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<OutputMemoList>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var list = operateContext.bllSession.T_VRDDEvent.GetMemoList(param);
            return ApiResultJsonModel<List<OutputMemoList>>.RedirectWebApi(WebResultCode.Ok, "获取事件列表成功！", list);
        }
        #endregion

        #region 2.8 ✔获取事件提醒日期列表 + WebApiResultJsonModel GetMemoDateList(InputMemoDateList param)
        /// <summary>
        ///  2.8 ✔获取事件提醒日期列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<List<OutputMemoDateList>> GetMemoDateList(InputMemoDateList param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<OutputMemoDateList>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var list = operateContext.bllSession.T_VRDDEvent.GetMemoDateList(param);
            return ApiResultJsonModel<List<OutputMemoDateList>>.RedirectWebApi(WebResultCode.Ok, "获取事件列表成功！", list);
        }
        #endregion

        #region 2.9 ✔添加自定义事件类型 + WebApiResultJsonModel AddMemoType(InputMemoType param)
        /// <summary>
        ///  2.9 ✔添加自定义事件类型
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> AddMemoType(InputMemoType param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            T_User user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userID));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "用户id信息异常~", null);
            var o = operateContext.bllSession.T_VRDDEventCType.FindSingle(s => s.userid.Equals(param.userID) && s.memoType.Equals(param.memoType));
            int mark = 1;
            T_VRDDEventCType obj = new T_VRDDEventCType
            {
                userid = param.userID,
                memoType = param.memoType,
                createName = user.user_name,
                createDate = DateTime.Now
            };
            if (o != null)
            {
                obj.memoTypeID = o.memoTypeID;
                //更新
                operateContext.bllSession.T_VRDDEventCType.Modify(obj, s => s.memoTypeID == o.memoTypeID, "memoType");
            }
            else
                mark = operateContext.bllSession.T_VRDDEventCType.Add(obj);
            if (mark > 0)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "添加自定义事件类型成功！", obj.memoTypeID);
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "添加失败！", null);
        }
        #endregion

        #region 2.10 ✔获取事件类型列表 + WebApiResultJsonModel GetMemoTypeList(InputMemoTypeList param)
        /// <summary>
        ///  2.10 ✔获取事件类型列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<List<OutputMemoTypeList>> GetMemoTypeList(InputMemoTypeList param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<OutputMemoTypeList>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            List<T_VRDDEventCType> list = new List<T_VRDDEventCType>();
            //公用
            if (param.type == 0)
                list = operateContext.bllSession.T_VRDDEventCType.Select(s => string.IsNullOrEmpty(s.userid));
            //用户事件
            else if (param.type == 1)
                list = operateContext.bllSession.T_VRDDEventCType.Select(s => s.userid.Equals(param.userID));
            else
                list = operateContext.bllSession.T_VRDDEventCType.Select(s => true);
            List<OutputMemoTypeList> result = new List<OutputMemoTypeList>();
            list?.ForEach(s => result.Add(new OutputMemoTypeList { memoTypeID = s.memoTypeID, memoType = s.memoType }));
            return ApiResultJsonModel<List<OutputMemoTypeList>>.RedirectWebApi(WebResultCode.Ok, "获取事件类型列表成功！", result);
        }
        #endregion

        #region 2.11 ✔删除事件类型 + WebApiResultJsonModel DeleteMemoType(InputMemoTypeID param)
        /// <summary>
        ///  2.11 ✔删除事件类型
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel DeleteMemoType(InputMemoTypeID param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int mark = operateContext.bllSession.T_VRDDEventCType.Delete(s => s.memoTypeID == param.memoTypeID && s.userid.Equals(param.userID));
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "删除事件类型失败！", null);
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功删除事件类型！", null);
        }
        #endregion

        #region 2.12 ✔获取房屋图片信息 + WebApiResultJsonModel GetHouseImage(InputHouseInfo param)
        /// <summary>
        ///  2.12 ✔获取房屋图片信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<HouseImageDetial> GetHouseImage(InputHouseInfo param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<HouseImageDetial>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = 0;
            if (!string.IsNullOrEmpty(param.userID))
                user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userID);
            var obj = operateContext.bllSession.T_VRStayUserLog.GetHouseImages(param, user_id);
            return ApiResultJsonModel<HouseImageDetial>.RedirectWebApi(WebResultCode.Ok, "获取房屋图片信息成功！", obj);
        }
        #endregion

        #region 2.13 ✔获取事件提醒列表 + WebApiResultJsonModel GetMemoRemindList(InputMemoRemindList param)
        /// <summary>
        ///  2.13 ✔获取事件提醒列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<List<OutputMemoRemindList>> GetMemoRemindList(InputMemoRemindList param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<OutputMemoRemindList>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var list = operateContext.bllSession.T_VRDDEvent.GetMemoRemindList(param);
            return ApiResultJsonModel<List<OutputMemoRemindList>>.RedirectWebApi(WebResultCode.Ok, "获取事件列表成功！", list);
        }
        #endregion

        //*******************************************20220112【奇点元宇宙】需求文档******************************************
        #region 3.0 ✔新增应用商品信息 + WebApiResultJsonModel AddMetaAppInfo(InputProgram param)
        /// <summary>
        ///  3.0 ✔新增应用商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> AddMetaAppInfo(InputProgram param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "用户信息异常或不存在！", null);
            //判断应用id是否已经添加并上架
            var f = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.attach_url.Equals(param.appID) && (s.file_status == 1 || s.file_status == 5));
            if (f != null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, $"当前指定应用id={param.appID}已在待审核或已上架！", f.file_id);
            //判断folderId是否存在
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, $"当前指定的folder_id={param.folderID}后台不存在！", null);
            T_DocumentInfo file = param.ToEntity();
            file.create_id = user.user_id;
            file.create_name = user.user_name;
            file.create_time = DateTime.Now;
            //其他默认值
            file.update_name = user.user_name;
            file.update_time = DateTime.Now;
            file.pro_type = 6;
            file.page_type = "QDMetaProgram";
            file.isEntity = false;
            file.file_status = 1;
            string folderNum = operateContext.bllSession.T_SysModule.FindSingle(s => s.folder_code.Equals("QDMeta"))?.file_header;
            folderNum = folderNum + DateTime.Now.ToString("yyyyMMddhhmmss");
            file.file_code = folderNum;
            file.folder_num = folderNum;
            if (param.listPrice != null && param.listPrice.Count > 0)
                //最小金额
                file.file_money = param.listPrice.Min(s => s.price);
            //添加
            int mark = operateContext.bllSession.T_DocumentInfo.Add(file);
            if (mark > 0)
            {
                //处理商品导航树对应关系
                operateContext.bllSession.T_DocumentFolderRelation.Add(new T_DocumentFolderRelation { file_id = file.file_id, create_id = file.create_id, folder_id = folder.folder_id, folder_path = folder.folder_path });
                //处理价格
                if (param.listPrice != null && param.listPrice.Count > 0)
                {
                    param.listPrice.ForEach(o => operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                    {
                        op_code = Helper.GetGuid,
                        file_id = file.file_id,
                        file_code = file.file_code,
                        price_name = o.month > 0 ? o.month.ToString() + "个月价格" : "无限期价格",
                        op_month = o.month,
                        ori_price = o.price
                    }));
                }
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "添加应用成功！", file.file_id);
            }
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Error, "添加应用失败！", null);
        }
        #endregion

        #region 3.1 ✔编辑应用商品信息 + WebApiResultJsonModel EditMetaAppInfo(InputEditProgram param)
        /// <summary>
        ///  3.1 ✔编辑应用商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【317】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel EditMetaAppInfo(InputEditProgram param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户信息异常或不存在！", null);
            //判断folderId是否存在
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"当前指定的folder_id={param.folderID}后台不存在！", null);
            //判断商品是否存在
            var obj = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID && s.file_status == 5 && !s.if_remove);
            if (obj == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"商品id={param.fileID}已下架或不存在！", null);
            T_DocumentInfo file = param.ToEntity();
            //其他默认值
            file.update_name = user.user_name;
            file.update_time = DateTime.Now;
            if (param.listPrice != null && param.listPrice.Count > 0)
                file.file_money = param.listPrice.Min(s => s.price);
            else
                file.file_money = 0;
            //添加
            int mark = operateContext.bllSession.T_DocumentInfo.Modify(file, s => s.file_id == param.fileID, "update_name", "update_time", "file_name", "file_note", "pag_num", "store_id", "file_money", "image_url");
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"更新失败！", null);
            //处理商品导航树对应关系
            operateContext.bllSession.T_DocumentFolderRelation.Modify(new T_DocumentFolderRelation { folder_id = folder.folder_id, folder_path = folder.folder_path }, s => s.file_id == param.fileID, "folder_id", "folder_path");
            //处理价格
            operateContext.bllSession.T_VRGoodDisiPrice.Delete(s => s.file_id == param.fileID);
            if (param.listPrice != null && param.listPrice.Count > 0)
            {
                param.listPrice.ForEach(o => operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                {
                    op_code = Helper.GetGuid,
                    file_id = obj.file_id,
                    file_code = obj.file_code,
                    price_name = o.month > 0 ? o.month.ToString() + "个月价格" : "无限期价格",
                    op_month = o.month,
                    ori_price = o.price
                }));
            }
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "编辑应用成功！", null);
        }
        #endregion

        #region 3.2 ✔新增房间商品信息 + WebApiResultJsonModel AddMetaRoomInfo(InputRoom param)
        /// <summary>
        ///  3.2 ✔新增房间商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> AddMetaRoomInfo(InputRoom param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "用户信息异常或不存在！", null);
            //判断应用id是否存在
            var app = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.appFileID && s.file_status == 5 && !s.if_remove);
            if (app == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, $"当前指定应用id={param.appFileID}不存在或已下架！", null);
            //判断应用id是否已经添加并上架
            //var room = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.programId==app.file_id && s.attach_url.Equals(param.roomID) && (s.file_status == 1 || s.file_status == 5));
            //if (room != null)
            //    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, $"当前指定房间id={param.roomID}已在应用{param.appFileID}下的待审核或已上架！", room.file_id);
            T_DocumentInfo file = param.ToEntity();
            file.create_id = user.user_id;
            file.create_name = user.user_name;
            file.create_time = DateTime.Now;
            //其他默认值
            file.update_name = user.user_name;
            file.update_time = DateTime.Now;
            file.pro_type = 6;
            file.page_type = "QDMetaRoom";
            file.isEntity = false;
            file.file_status = 5;
            string folderNum = operateContext.bllSession.T_SysModule.FindSingle(s => s.folder_code.Equals("QDMeta"))?.file_header;
            folderNum = folderNum + DateTime.Now.ToString("yyyyMMddhhmmss");
            file.file_code = folderNum;
            file.folder_num = folderNum;
            file.programId = param.appFileID; //app.file_id;
            //添加
            int mark = operateContext.bllSession.T_DocumentInfo.Add(file);
            if (mark > 0)
            {
                if (param.price > 0)
                    operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                    {
                        op_code = Helper.GetGuid,
                        file_id = file.file_id,
                        file_code = file.file_code,
                        price_name = "无限期价格",
                        op_month = 0,
                        ori_price = param.price
                    });
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "添加房间成功！", file.file_id);
            }
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Error, "添加房间失败！", null);
        }
        #endregion

        #region 3.3 ✔编辑房间商品信息 + WebApiResultJsonModel EditMetaRoomInfo(InputEditRoom param)
        /// <summary>
        ///  3.3 ✔编辑房间商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel EditMetaRoomInfo(InputEditRoom param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户信息异常或不存在！", null);
            //判断应用id是否存在
            var app = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.attach_url.Equals(param.appFileID) && s.file_status == 5 && !s.if_remove);
            if (app == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"当前指定应用id={param.appFileID}不存在或已下架！", null);
            //判断商品是否存在
            var obj = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID && s.file_status == 5 && !s.if_remove);
            if (obj == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"商品id={param.fileID}已下架或不存在！", null);
            T_DocumentInfo file = param.ToEntity();
            //其他默认值
            file.update_name = user.user_name;
            file.update_time = DateTime.Now;
            file.programId = app.file_id;
            //添加
            int mark = operateContext.bllSession.T_DocumentInfo.Modify(file, s => s.file_id == param.fileID, "update_name", "update_time", "file_name", "file_note", "pag_num", "qr_code", "game_start", "attach_url", "game_end", "file_money", "programId");
            //处理价格
            operateContext.bllSession.T_VRGoodDisiPrice.Delete(s => s.file_id == param.fileID);
            if (param.price > 0)
            {
                operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                {
                    op_code = Helper.GetGuid,
                    file_id = obj.file_id,
                    file_code = obj.file_code,
                    price_name = "无限期价格",
                    op_month = 0,
                    ori_price = param.price
                });
            }
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "编辑房间成功！", null);
        }
        #endregion

        #region 3.4 ✔获取应用商品列表 + WebApiResultJsonModel GetMetaAppList(InputMetaAppList param)
        /// <summary>
        ///  3.4 ✔获取应用商品列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【333】<br/>
        /// </remarks> 
        [HttpPost]
        public WebApiResultJsonModel<List<OutputMetaResult>> GetMetaAppList(InputMetaAppList param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<OutputMetaResult>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            if (param.Type > -1 && string.IsNullOrEmpty(param.UserID))
                return ApiResultJsonModel<List<OutputMetaResult>>.RedirectWebApi(WebResultCode.Exception, "Type请求参数为0、1、2时UserID参数必传！", null);
            int user_id = 0, create_id = 0;
            if (!string.IsNullOrEmpty(param.createID))
                user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.createID);
            if (!string.IsNullOrEmpty(param.UserID))
                create_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.UserID);
            var list = operateContext.bllSession.T_VRDDEvent.GetMetaResult(param, user_id, create_id);
            return ApiResultJsonModel<List<OutputMetaResult>>.RedirectWebApi(WebResultCode.Ok, "获取应用商品列表成功！", list);
        }
        #endregion

        #region 3.5 ✔获取房间商品列表 + WebApiResultJsonModel GetMetaRoomList(InputMetaRoomList param)
        /// <summary>
        ///  3.5 ✔获取房间商品列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、需求变更： 禅道id：352 日期：2022-06-28<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<List<OutputMetaRoomResult>> GetMetaRoomList(InputMetaRoomList param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<OutputMetaRoomResult>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            if (param.Type > -1 && string.IsNullOrEmpty(param.UserID))
                return ApiResultJsonModel<List<OutputMetaRoomResult>>.RedirectWebApi(WebResultCode.Exception, "Type请求参数为0、1、2时UserID参数必传！", null);
            int user_id = 0, create_id = 0;
            if (!string.IsNullOrEmpty(param.createID))
                user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.createID);
            if (!string.IsNullOrEmpty(param.UserID))
                create_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.UserID);
            var list = operateContext.bllSession.T_VRDDEvent.GetMetaRoomResult(param, user_id, create_id);
            return ApiResultJsonModel<List<OutputMetaRoomResult>>.RedirectWebApi(WebResultCode.Ok, "获取房间商品列表成功！", list);
        }
        #endregion

        #region 3.6 ✔更新商品下载次数 + WebApiResultJsonModel UpdateGoodsDownNumber(InputGoodSpec param)
        /// <summary>
        ///  3.6 ✔更新商品下载次数
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel UpdateGoodsDownNumber(InputGoodSpec param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID && s.file_status == 5 && !s.if_remove);
            if (file == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"商品id={param.fileID}不存在或已下架！", null);
            int mark = operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { down_number = file.down_number + 1 }, s => s.file_id == param.fileID, "down_number");
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "更新商品下载次数失败！", null);
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功更新商品下载次数！", null);
        }
        #endregion

        #region 3.7 ✔更新商品在线人数 + WebApiResultJsonModel UpdateGoodsOnlineNumber(InputOnlineNumber param)
        /// <summary>
        ///  3.7 ✔更新商品在线人数
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel UpdateGoodsOnlineNumber(InputOnlineNumber param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID && s.file_status == 5 && !s.if_remove);
            if (file == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"商品id={param.fileID}不存在或已下架！", null);
            operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { play_num = param.number }, s => s.file_id == param.fileID, "play_num");
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功更新商品在线人数！", null);
        }
        #endregion

        //*******************************************20220314需求文档******************************************
        #region 4.1 ✔新增元宇宙素材商品信息 + async Task<WebApiResultJsonModel<int>> AddMaterialInfo(AddMaterialParam param)
        /// <summary>
        ///  4.1 ✔新增元宇宙素材商品信息
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> AddMaterialInfo(AddMaterialParam param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            string msg = param.verifyData();
            if (!string.IsNullOrEmpty(msg))
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, msg, null);
            //1、获取登录用户
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "登录用户id信息异常！", null);
            //2、获取目录树
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "目录导航树id信息异常！", null);
            T_DocumentInfo file = param.toEntry();
            file.create_id = user.user_id;
            file.create_name = user.user_name;
            file.update_name = user.user_name;
            string folderNum = operateContext.bllSession.T_SysModule.FindSingle(s => s.folder_code.Equals("QDMeta"))?.file_header;
            folderNum = folderNum + DateTime.Now.ToString("yyyyMMddhhmmss");
            file.file_code = folderNum;
            file.folder_num = folderNum;
            if (param.listPrice != null && param.listPrice.Count > 0)
                file.file_money = param.listPrice.Min(s => s.price);
            //添加
            int mark = operateContext.bllSession.T_DocumentInfo.Add(file);
            if (mark > 0)
            {
                //处理商品导航树对应关系
                operateContext.bllSession.T_DocumentFolderRelation.Add(new T_DocumentFolderRelation { file_id = file.file_id, create_id = file.create_id, folder_id = folder.folder_id, folder_path = folder.folder_path });
                //处理价格
                if (param.listPrice != null && param.listPrice.Count > 0)
                {
                    param.listPrice.ForEach(o => operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                    {
                        op_code = Helper.GetGuid,
                        file_id = file.file_id,
                        file_code = file.file_code,
                        price_name = o.month > 0 ? o.month.ToString() + "个月价格" : "无限期价格",
                        op_month = o.month,
                        ori_price = o.price
                    }));
                }
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "新增元宇宙素材商品信息成功！", file.file_id);
            }
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Error, "新增元宇宙素材商品信息失败！", null);
        }
        #endregion

        #region 4.2 ✔审核素材商品信息 + WebApiResultJsonModel CheckMaterialInfo(CheckMaterialInput param)
        /// <summary>
        ///  4.2 ✔审核素材商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【322】<br/>
        /// </remarks> 
        [HttpPost]
        public WebApiResultJsonModel CheckMaterialInfo(CheckMaterialInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            string msg = param.verifyData();
            if (!string.IsNullOrEmpty(msg))
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, msg, null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"用户id={param.userid}不存在！", null);
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID && s.file_status == 1);
            if (file == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"商品id={param.fileID}不存在或已不是待审核！", null);
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"所属目录id={param.folderID}不存在！", null);
            int mark = operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo
            {
                file_name = param.fileName,
                file_note = param.fileNote,
                image_url = param.imageUrl,
                file_status = param.fileStatus,
                approve_note = param.approveNote,
                approve_name = user.user_name,
                approve_time = DateTime.Now
            }, s => s.file_id == param.fileID, "file_name", "file_note", "image_url", "file_status", "approve_note", "approve_name", "approve_time");
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "审核素材商品信息失败！", null);
            //更新商品-目录关系
            var rel = operateContext.bllSession.T_DocumentFolderRelation.FindSingle(s => s.file_id == param.fileID);
            if (rel == null)
                //新增
                operateContext.bllSession.T_DocumentFolderRelation.Add(new T_DocumentFolderRelation
                {
                    file_id = param.fileID,
                    folder_id = folder.folder_id,
                    folder_path = folder.folder_path,
                    create_id = user.user_id
                });
            else
                //编辑
                operateContext.bllSession.T_DocumentFolderRelation.Modify(new T_DocumentFolderRelation
                {
                    folder_id = folder.folder_id,
                    folder_path = folder.folder_path,
                    create_id = user.user_id
                }, s => s.fr_id == rel.fr_id, "folder_id", "folder_path", "create_id");
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功审核素材商品信息！", null);
        }
        #endregion

        #region 4.3 ✔编辑素材商品信息 + WebApiResultJsonModel EditMaterialInfo(EditMaterialParam param)
        /// <summary>
        ///  4.3 ✔编辑素材商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【321】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel EditMaterialInfo(EditMaterialParam param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            string msg = param.verifyData();
            if (!string.IsNullOrEmpty(msg))
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, msg, null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"用户id={param.userid}不存在！", null);
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID && !s.if_remove);
            if (file == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"商品id={param.fileID}不存在或已删除！", null);
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"所属目录id={param.folderID}不存在！", null);
            var obj = new T_DocumentInfo
            {
                file_name = param.fileName,
                file_note = param.fileNote,
                image_url = param.imageUrl,
                update_name = user.user_name,
                update_time = DateTime.Now
            };
            if (param.listPrice != null && param.listPrice.Count > 0)
                file.file_money = param.listPrice.Min(s => s.price);
            else
                file.file_money = 0;
            int mark = operateContext.bllSession.T_DocumentInfo.Modify(obj, s => s.file_id == param.fileID, "file_name", "file_note", "image_url", "update_name", "update_time", "file_money");
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "编辑素材商品信息失败！", null);
            //更新价格表
            operateContext.bllSession.T_VRGoodDisiPrice.Delete(s => s.file_id == param.fileID);
            param.listPrice.ForEach(o => operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
            {
                op_code = Helper.GetGuid,
                file_id = file.file_id,
                file_code = file.file_code,
                price_name = o.month > 0 ? o.month.ToString() + "个月价格" : "无限期价格",
                op_month = o.month,
                ori_price = o.price
            }));
            //更新商品-目录关系
            var rel = operateContext.bllSession.T_DocumentFolderRelation.FindSingle(s => s.file_id == param.fileID);
            if (rel == null)
                //新增
                operateContext.bllSession.T_DocumentFolderRelation.Add(new T_DocumentFolderRelation
                {
                    file_id = param.fileID,
                    folder_id = folder.folder_id,
                    folder_path = folder.folder_path,
                    create_id = user.user_id
                });
            else
                //编辑
                operateContext.bllSession.T_DocumentFolderRelation.Modify(new T_DocumentFolderRelation
                {
                    folder_id = folder.folder_id,
                    folder_path = folder.folder_path,
                    create_id = user.user_id
                }, s => s.fr_id == rel.fr_id, "folder_id", "folder_path", "create_id");
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功编辑素材商品信息！", null);
        }
        #endregion

        #region 4.4 ✔获取素材商品列表 + WebApiResultJsonModel GetMaterialList(MaterialListInput param)
        /// <summary>
        ///  4.4 ✔获取素材商品列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<BasePage<MaterialListOutput>> GetMaterialList(MaterialListInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<BasePage<MaterialListOutput>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userID);
            int create_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.createID);
            var result = operateContext.bllSession.T_VRDDEvent.GetMaterialList(param, user_id, create_id);
            return ApiResultJsonModel<BasePage<MaterialListOutput>>.RedirectWebApi(WebResultCode.Ok, "成功获取素材商品列表！", result);
        }
        #endregion


        //*******************************************20220318需求文档******************************************
        #region 5.0 ✔获取待审核应用数量 + WebApiResultJsonModel GetNewAppNumber(BaseDDAPI param)
        /// <summary>
        ///  5.0 ✔获取待审核应用数量
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> GetNewAppNumber(BaseDDAPI param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int count = operateContext.bllSession.T_DocumentInfoLog.SelectCount(s => s.file_status == 1 && s.page_type.Equals("QDMeta"));
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "成功获取待审核应用数量！", count);
        }
        #endregion

        #region 5.1 ✔获取待审核素材数量 + WebApiResultJsonModel GetNewMaterialNumber(BaseDDAPI param)
        /// <summary>
        ///  5.1 ✔获取待审核素材数量
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> GetNewMaterialNumber(BaseDDAPI param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int count = operateContext.bllSession.T_DocumentInfo.SelectCount(s => s.file_status == 1 && s.page_type.Equals("QDMaterial"));
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "成功获取待审核素材数量！", count);
        }
        #endregion


        #region 4.4 ✔测试base64上传视频 + WebApiResultJsonModel UploadVideoByJson(VideoJson param)
        /// <summary>
        ///  4.4 ✔测试base64上传视频
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel UploadVideoByJson(VideoJson param)
        {
            string pathServer = "/uploadFile/VRVideoFile/" + DateTime.Now.ToString("yyyyMMdd") + "/Breviary/";
            string uploadPath = request.MapPath(request.ApplicationPath + pathServer);
            if (!Directory.Exists(uploadPath))
                Directory.CreateDirectory(uploadPath);
            string picName = Guid.NewGuid().ToString().Replace("-", ""),
                prefixStr = param.video.Split(';')[0].ToString().Split('/')[1];
            byte[] picByte = Convert.FromBase64String(param.video.Split(',')[1]);
            string url = FileHelper.SaveFileByBase64(uploadPath + picName + "." + prefixStr, picByte);
            if (!string.IsNullOrEmpty(url))
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "视频上传成功！", "~" + pathServer + picName + "." + prefixStr);
            else
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Error, "视频上传失败！", null);
        }
        #endregion

        //*******************************************20220416需求文档******************************************
        #region 6.1 ✔保存视频动态 + WebApiResultJsonModel SaveVideoNews(VideoNewsInput param)
        /// <summary>
        ///  6.1 ✔保存视频动态
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 返回视频动态id<br/>
        /// 2. 20220623度度圈需求3.5优化
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<int?> SaveVideoNews(VideoNewsInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "用户编码userid信息有误，请核实！", null);
            var dy = param.toEntry();
            dy.create_id = user.user_id;
            dy.create_name = user.user_name;
            if (dy.fileID > 0)
            {
                var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == dy.fileID);
                if (file == null || file.file_status == 4)
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "当前商品id后台已下架或不存在！", null);
                if (file.page_type.Equals("QDMetaProgram"))
                    dy.fileType = 1;//应用
                else if (file.page_type.Equals("QDMetaRoom"))
                    dy.fileType = 2;//房间
                else
                    dy.fileType = 3;//度度圈商品
            }
            int mark = operateContext.bllSession.T_VRDDVideoDynamic.Add(dy);
            if(mark<=0)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "保存视频动态失败！", null);
            //获取积分来源【汇总表】对应的数据
            var ssmInfo = operateContext.bllSession.T_VRScoreSourceMain.FindSingle(o => o.userid.Equals(param.userid) && o.itemType.Equals("PostVideo") && o.proType.Equals("VMeta"));
            decimal inScore = 1,//收入
                totalScore = 1;//余额
            if (null != ssmInfo)
            {
                inScore = ssmInfo.inScore + 1;
                totalScore = ssmInfo.totalScore + 1;
            }
            //保存明细
            mark = operateContext.bllSession.T_VRScoreSourceDetail.Add(new T_VRScoreSourceDetail
            {
                logCode = Helper.GetGuid,
                userid = user.user_guid,
                user_id = user.user_id,
                user_name = user.user_name,
                itemType = "PostVideo",
                inScore = 1,
                outScore = 0,
                totalScore = totalScore,
                proType = "VMeta",
                createDate = DateTime.Now,
                scoreNote = "发布视频"
            });
            //更新积分来源汇总
            if (mark > 0)
            {
                if (null != ssmInfo)
                    operateContext.bllSession.T_VRScoreSourceMain.Modify(new T_VRScoreSourceMain { inScore = inScore, totalScore = totalScore, updateDate = DateTime.Now }, s => s.logCode.Equals(ssmInfo.logCode), "inScore", "totalScore", "updateDate");
                else
                    operateContext.bllSession.T_VRScoreSourceMain.Add(new T_VRScoreSourceMain
                    {
                        logCode = Helper.GetGuid,
                        userid = user.user_guid,
                        user_id = user.user_id,
                        user_name = user.user_name,
                        itemType = "PostVideo",
                        proType = "VMeta",
                        inScore = inScore,
                        outScore = 0,
                        totalScore = totalScore,
                        scoreNote = "发布视频",
                        createDate = DateTime.Now,
                        updateDate = DateTime.Now
                    });
            }
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "成功保存视频动态！", dy.newsID);
        }
        #endregion

        #region 6.2 ✔获取我的视频动态列表 + WebApiResultJsonModel GetMyVideoNews(MyVideoNewsInput param)
        /// <summary>
        ///  6.2 ✔获取我的视频动态列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<BasePage<MyVideoNewsOutput>> GetMyVideoNews(MyVideoNewsInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<BasePage<MyVideoNewsOutput>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int create_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.createid);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userid);
            var result = operateContext.bllSession.T_VRDDVideoDynamic.GetMyVideoNews(param, create_id, user_id);
            return ApiResultJsonModel<BasePage<MyVideoNewsOutput>>.RedirectWebApi(WebResultCode.Ok, "成功获取我的视频动态列表！", result);
        }
        #endregion

        #region 6.3 ✔获取有动态的日期列表 + WebApiResultJsonModel GetVideoNewsDateList(VideoNewsDateInput param)
        /// <summary>
        ///  6.3 ✔获取有动态的日期列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<WebApiResultJsonModel<List<VideoNewsDateOutput>>> GetVideoNewsDateList(VideoNewsDateInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<VideoNewsDateOutput>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var result = await operateContext.bllSession.T_VRDDVideoDynamic.GetVideoNewsDateList(param);
            return ApiResultJsonModel<List<VideoNewsDateOutput>>.RedirectWebApi(WebResultCode.Ok, "成功获取我的视频动态列表！", result);
        }
        #endregion

        #region 6.4 ✔下架视频动态 + WebApiResultJsonModel TakeDownVideoNews(DownVideoNewsInput param)
        /// <summary>
        ///  6.4 ✔下架视频动态
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel TakeDownVideoNews(DownVideoNewsInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            //判断动态是否存在
            var dy = operateContext.bllSession.T_VRDDVideoDynamic.FindSingle(s => s.newsID == param.newsID);
            if (dy == null || dy.newsStatus == 1)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "动态已下架或不存在！", null);
            int mark = operateContext.bllSession.T_VRDDVideoDynamic.Modify(new T_VRDDVideoDynamic { newsStatus = 1 }, s => s.newsID == param.newsID, "newsStatus");
            if (mark > 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功下架视频动态！", null);
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "下架视频动态失败！", null);
        }
        #endregion

        #region 6.5 ✔删除视频动态 + WebApiResultJsonModel DeleteVideoNews(DownVideoNewsInput param)
        /// <summary>
        ///  6.5 ✔删除视频动态
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel DeleteVideoNews(DownVideoNewsInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            //判断动态是否存在
            var dy = operateContext.bllSession.T_VRDDVideoDynamic.FindSingle(s => s.newsID == param.newsID);
            if (dy == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "动态不存在或已被删除！", null);
            int mark = operateContext.bllSession.T_VRDDVideoDynamic.Delete(s => s.newsID == param.newsID);
            if (mark > 0)
            {
                //删除给此动态点赞的记录
                operateContext.bllSession.T_VRDDUserVideoDynamicStar.Delete(s => s.newsID == param.newsID);
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功删除视频动态！", null);
            }
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "删除视频动态失败！", null);
        }
        #endregion

        #region 6.6 ✔获取视频动态列表 + WebApiResultJsonModel GetVideoNews(VideoNewsListInput param)
        /// <summary>
        ///  6.6 ✔获取视频动态列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<BasePage<VideoNewsListOutput>> GetVideoNews(VideoNewsListInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<BasePage<VideoNewsListOutput>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userid);
            var result = operateContext.bllSession.T_VRDDVideoDynamic.GetVideoNews(param, user_id);
            return ApiResultJsonModel<BasePage<VideoNewsListOutput>>.RedirectWebApi(WebResultCode.Ok, "成功获取视频动态列表！", result);
        }
        #endregion

        #region 6.7 ✔保存视频动态点赞 + WebApiResultJsonModel SaveVideoNewsStar(SaveVideoNewsStarInput param)
        /// <summary>
        ///  6.7 ✔保存视频动态点赞
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> SaveVideoNewsStar(SaveVideoNewsStarInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            //判断动态是否存在
            var dy = operateContext.bllSession.T_VRDDVideoDynamic.FindSingle(s => s.newsID == param.newsID);
            if (dy == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "动态不存在或已被删除！", null);
            int mark = operateContext.bllSession.T_VRDDUserVideoDynamicStar.SelectCount(s => s.userid == param.userid && s.newsID == param.newsID);
            //添加点赞
            if (param.type == 1)
            {
                if (mark > 0)
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "已成功无需重复点赞！", dy.starNum);
                mark = operateContext.bllSession.T_VRDDUserVideoDynamicStar.Add(new T_VRDDUserVideoDynamicStar { userid = param.userid, newsID = param.newsID, star_date = DateTime.Now });
                if (mark > 0)
                {
                    //点赞数+1
                    int starNum = dy.starNum + 1;
                    operateContext.bllSession.T_VRDDVideoDynamic.Modify(new T_VRDDVideoDynamic { starNum = starNum }, s => s.newsID == param.newsID, "starNum");
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "已成功点赞！", starNum);
                }
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "点赞失败！", null);
            }
            //取消点赞
            else
            {
                if (mark <= 0)
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "尚未点赞无需取消！", null);
                mark = operateContext.bllSession.T_VRDDUserVideoDynamicStar.Delete(s => s.userid == param.userid && s.newsID == param.newsID);
                if (mark > 0)
                {
                    //点赞数-1
                    int starNum = dy.starNum - 1;
                    if (dy.starNum > 0)
                        starNum = dy.starNum - 1;
                    else
                        starNum = 0;
                    operateContext.bllSession.T_VRDDVideoDynamic.Modify(new T_VRDDVideoDynamic { starNum = starNum }, s => s.newsID == param.newsID, "starNum");
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "取消成功！", starNum);
                }
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "取消失败！", null);
            }
        }
        #endregion

        #region 6.8 ✔新增视频分享次数 + WebApiResultJsonModel AddVideoNewsSharedNum(DownVideoNewsInput param)
        /// <summary>
        ///  6.8 ✔新增视频分享次数
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel AddVideoNewsSharedNum(DownVideoNewsInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            //判断动态是否存在
            var dy = operateContext.bllSession.T_VRDDVideoDynamic.FindSingle(s => s.newsID == param.newsID);
            if (dy == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "动态不存在或已被删除！", null);
            int mark = operateContext.bllSession.T_VRDDVideoDynamic.Modify(new T_VRDDVideoDynamic { sharedNum = dy.sharedNum + 1 }, s => s.newsID == param.newsID, "sharedNum");
            if (mark > 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功分享动态！", null);
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "分享动态失败！", null);
        }
        #endregion

        #region 6.9 ✔获取房间商品详情 + WebApiResultJsonModel GetMetaRoomDetail(MetaRoomDetailInput param)
        /// <summary>
        ///  6.9 ✔获取房间商品详情
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 2022-06-21 :禅道需求 341
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<MetaRoomDetailOutput> GetMetaRoomDetail(MetaRoomDetailInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<MetaRoomDetailOutput>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userID);
            var result = operateContext.bllSession.T_VRDDVideoDynamic.GetMetaRoomDetail(param, user_id);
            return ApiResultJsonModel<MetaRoomDetailOutput>.RedirectWebApi(WebResultCode.Ok, "成功获取房间商品详情！", result);
        }
        #endregion

        //*******************************************20220421需求文档******************************************
        #region 7.1 ✔提交素材信息 + async Task<WebApiResultJsonModel<int>> SubmitMaterialInfo(AddMaterialInfo param)
        /// <summary>
        ///  7.1 ✔提交素材信息
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        /// <remarks>
        /// 返回商品id<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<int?> SubmitMaterialInfo(AddMaterialInfo param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            string msg = param.verifyData();
            if (!string.IsNullOrEmpty(msg))
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, msg, null);
            //1、获取登录用户
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "登录用户id信息异常！", null);
            //2、获取目录树
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "目录导航树id信息异常！", null);
            T_DocumentInfo file = param.toEntry();
            file.create_id = user.user_id;
            file.create_name = user.user_name;
            file.update_name = user.user_name;
            string folderNum = operateContext.bllSession.T_SysModule.FindSingle(s => s.folder_code.Equals("QDMeta"))?.file_header;
            folderNum = folderNum + DateTime.Now.ToString("yyyyMMddhhmmss");
            file.file_code = folderNum;
            file.folder_num = folderNum;
            //添加
            int mark = operateContext.bllSession.T_DocumentInfo.Add(file);
            if (mark > 0)
            {
                //处理商品导航树对应关系
                operateContext.bllSession.T_DocumentFolderRelation.Add(new T_DocumentFolderRelation { file_id = file.file_id, create_id = file.create_id, folder_id = folder.folder_id, folder_path = folder.folder_path });
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "提交素材信息成功！", file.file_id);
            }
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Error, "提交素材信息失败！", null);
        }
        #endregion

        #region 7.2 ✔发布素材商品信息 + WebApiResultJsonModel ReleaseMaterialInfo(ReleaseMaterialParam param)
        /// <summary>
        ///  7.2 ✔发布素材商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【320】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel ReleaseMaterialInfo(ReleaseMaterialParam param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            string msg = param.verifyData();
            if (!string.IsNullOrEmpty(msg))
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, msg, null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"用户id={param.userid}不存在！", null);
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID);
            if (file == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"商品id={param.fileID}不存在或已被删除！", null);
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"所属目录id={param.folderID}不存在！", null);
            decimal price = 0;
            if (param.listPrice != null && param.listPrice.Count > 0)
                price = param.listPrice.OrderBy(s => s.price).FirstOrDefault().price;
            int mark = operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo
            {
                file_name = param.fileName,
                file_note = param.fileNote,
                image_url = param.imageUrl,
                file_status = 1,
                file_money = price,//最低价格
                issue_start = DateTime.Now
            }, s => s.file_id == param.fileID, "file_name", "file_note", "image_url", "file_status", "issue_start", "file_money");
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "发布素材商品信息失败！", null);
            //更新商品-目录关系
            var rel = operateContext.bllSession.T_DocumentFolderRelation.FindSingle(s => s.file_id == param.fileID);
            if (rel == null)
                //新增
                operateContext.bllSession.T_DocumentFolderRelation.Add(new T_DocumentFolderRelation
                {
                    file_id = param.fileID,
                    folder_id = folder.folder_id,
                    folder_path = folder.folder_path,
                    create_id = user.user_id
                });
            else
                //编辑
                operateContext.bllSession.T_DocumentFolderRelation.Modify(new T_DocumentFolderRelation
                {
                    folder_id = folder.folder_id,
                    folder_path = folder.folder_path,
                    create_id = user.user_id
                }, s => s.fr_id == rel.fr_id, "folder_id", "folder_path", "create_id");
            //更新价格列表
            operateContext.bllSession.T_VRGoodDisiPrice.Delete(s => s.file_id == param.fileID);
            if (param.listPrice != null && param.listPrice.Count > 0)
            {
                param.listPrice.ForEach(o => operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                {
                    op_code = Helper.GetGuid,
                    file_id = file.file_id,
                    file_code = file.file_code,
                    price_name = o.month > 0 ? o.month.ToString() + "个月价格" : "无限期价格",
                    op_month = o.month,
                    ori_price = o.price
                }));
            }
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "成功发布素材商品信息！", null);
        }
        #endregion

        #region 7.3 ✔获取素材商品详情 + WebApiResultJsonModel GetMaterialDetail(MaterialDetailInput param)
        /// <summary>
        ///  7.3 ✔获取素材商品详情
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<MaterialDetailOutput> GetMaterialDetail(MaterialDetailInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<MaterialDetailOutput>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userID);
            var result = operateContext.bllSession.T_VRDDVideoDynamic.GetMaterialDetail(param, user_id);
            return ApiResultJsonModel<MaterialDetailOutput>.RedirectWebApi(WebResultCode.Ok, "成功获取素材商品详情！", result);
        }
        #endregion


        //*******************************************20220505【奇点元宇宙】需求文档******************************************
        #region 8.0 ✔发布应用商品信息 + WebApiResultJsonModel ReleaseMetaAppInfo(MetaAppInfoInput param)
        /// <summary>
        ///  8.0 ✔发布应用商品信息
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<int?> ReleaseMetaAppInfo(MetaAppInfoInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, "用户信息异常或不存在！", null);
            //判断folderId是否存在
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, $"当前指定的folder_id={param.folderID}后台不存在！", null);
            int file_id = 0, file_order = 0;
            string file_code = string.Empty;
            StringBuilder listPrice = new StringBuilder();
            //判断商品是否存在
            if (param.fileID > 0)
            {
                //判断商品id是否存在
                var f = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID);
                if (f == null)
                    return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Exception, $"当前指定商品id={param.fileID}不存在或已下架无法发布新版本！", null);
                file_id = f.file_id;
                file_code = f.file_code;
                file_order = f.file_order;
            }
            #region 新增应用
            if (param.fileID <= 0)
            {
                T_DocumentInfo file = param.ToDocInfoEntity();
                file.create_id = user.user_id;
                file.create_name = user.user_name;
                file.create_time = DateTime.Now;
                //其他默认值
                file.update_name = user.user_name;
                file.update_time = DateTime.Now;
                string folderNum = operateContext.bllSession.T_SysModule.FindSingle(s => s.folder_code.Equals("QDMeta"))?.file_header;
                folderNum = folderNum + DateTime.Now.ToString("yyyyMMddhhmmss");
                file.file_code = folderNum;
                file.folder_num = folderNum;
                if (param.listPrice != null && param.listPrice.Count > 0)
                    //最小金额
                    file.file_money = param.listPrice.Min(s => s.price);
                //添加
                int mark = operateContext.bllSession.T_DocumentInfo.Add(file);
                if (mark > 0)
                {
                    file_id = file.file_id;
                    file_code = file.file_code;
                    //处理商品导航树对应关系
                    operateContext.bllSession.T_DocumentFolderRelation.Add(new T_DocumentFolderRelation { file_id = file.file_id, create_id = file.create_id, folder_id = folder.folder_id, folder_path = folder.folder_path });
                    //处理价格
                    if (param.listPrice != null && param.listPrice.Count > 0)
                    {
                        param.listPrice.ForEach(o => operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                        {
                            op_code = Helper.GetGuid,
                            file_id = file.file_id,
                            file_code = file.file_code,
                            price_name = o.month > 0 ? o.month.ToString() + "个月价格" : "无限期价格",
                            op_month = o.month,
                            ori_price = o.price
                        }));
                    }
                }
            }
            else
            {
                //更新时间
                operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { create_time = DateTime.Now, update_name = user.user_name, update_time = DateTime.Now }, s => s.file_id == param.fileID, "create_time", "update_name", "update_time");
            }
            #endregion
            //处理价格
            if (param.listPrice != null && param.listPrice.Count > 0)
                param.listPrice.ForEach(o => listPrice.Append($"{o.month}:{o.price},"));
            T_DocumentInfoLog fileLog = param.ToDocInfoLogEntity();
            fileLog.folder_name = folder.folder_name;
            fileLog.file_id = file_id;
            fileLog.file_code = file_code;
            fileLog.create_id = user.user_id;
            fileLog.create_name = user.user_name;
            fileLog.create_time = DateTime.Now;
            //其他默认值
            fileLog.update_name = user.user_name;
            fileLog.update_time = DateTime.Now;
            fileLog.file_order = file_order;
            if (param.listPrice != null && param.listPrice.Count > 0)
                //最小金额
                fileLog.file_money = param.listPrice.Min(s => s.price);
            fileLog.listPrice = listPrice.ToString()?.Trim(',');
            //判断当前新增版本是否在待审核
            if (param.fileID > 0)
            {
                var log = operateContext.bllSession.T_DocumentInfoLog.FindSingle(s => s.file_id == fileLog.file_id && s.file_status == 1);
                if (log != null)
                    //编辑
                    operateContext.bllSession.T_DocumentInfoLog.Modify(fileLog, s => s.version_id == log.version_id, "file_code", "file_name", "file_note", "pag_num", "finish_time", "folder_id", "folder_name", "attach_url", "image_url", "doc_number", "file_size", "file_money", "listPrice", "store_id", "create_id", "create_name", "create_time", "update_name", "update_time", "versionNote");
                else
                    operateContext.bllSession.T_DocumentInfoLog.Add(fileLog);
            }
            else
                operateContext.bllSession.T_DocumentInfoLog.Add(fileLog);
            return ApiResultJsonModel<int?>.RedirectWebApi(WebResultCode.Ok, "成功发布应用商品信息！", file_id);
        }
        #endregion

        #region 8.1 ✔获取待审核应用列表 + WebApiResultJsonModel GetMetaAppPendingList(AppPendingListInput param)
        /// <summary>
        ///  8.1 ✔获取待审核应用列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<BasePage<AppPendingListOutput>> GetMetaAppPendingList(AppPendingListInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<BasePage<AppPendingListOutput>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.createID);
            var result = operateContext.bllSession.T_DocumentInfoLog.GetMetaAppPendingList(param, user_id);
            return ApiResultJsonModel<BasePage<AppPendingListOutput>>.RedirectWebApi(WebResultCode.Ok, "成功获取待审核应用列表！", result);
        }
        #endregion

        #region 8.2 ✔审核应用商品信息 + WebApiResultJsonModel CheckMetaAppInfo(CheckMetaAppInput param)
        /// <summary>
        ///  8.2 ✔审核应用商品信息
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【318】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel CheckMetaAppInfo(CheckMetaAppInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            if (param.fileStatus == 6 && string.IsNullOrEmpty(param.approveNote))
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "审核不通过时请填写审核意见！", null);
            //1、判断商品id是否存在被审核表
            var fileLog = operateContext.bllSession.T_DocumentInfoLog.FindSingle(s => s.file_id == param.fileID && s.file_status == 1);
            if (fileLog == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"当前商品id={param.fileID}不存在或已不在待审核！", null);
            //判断folderId是否存在
            var folder = operateContext.bllSession.T_DocumentFolder.FindSingle(s => s.folder_id == param.folderID);
            if (folder == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, $"当前指定的folder_id={param.folderID}后台不存在！", null);
            var user = operateContext.bllSession.T_User.FindSingle(s => s.user_guid.Equals(param.userid));
            if (user == null)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户信息异常或不存在！", null);
            fileLog.approve_note = param.approveNote;
            fileLog.image_url = param.imageUrl;
            fileLog.file_name = param.fileName;
            fileLog.file_note = param.fileNote;
            fileLog.folder_id = param.folderID;
            fileLog.folder_name = folder.folder_name;
            fileLog.store_id = param.folderID;
            fileLog.file_status = param.fileStatus;
            fileLog.approve_name = user.user_name;
            fileLog.approve_time = DateTime.Now;
            fileLog.update_name = user.user_name;
            fileLog.update_time = DateTime.Now;
            int mark = operateContext.bllSession.T_DocumentInfoLog.Modify(fileLog, s => s.version_id == fileLog.version_id, "file_name", "file_note", "folder_id", "folder_name", "store_id", "file_status", "approve_name", "approve_time", "approve_note", "update_name", "update_time");
            if (mark <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "审核失败！", null);
            //数据更新至正式表
            if (param.fileStatus == 5)
            {
                var file = param.ToDocInfoEntity(fileLog);
                file.if_remove = false;
                mark = operateContext.bllSession.T_DocumentInfo.Modify(file, s => s.file_id == param.fileID, "file_name", "file_note", "pag_num", "finish_time", "attach_url", "image_url", "doc_number", "file_size", "create_name", "create_id", "create_time", "update_name", "update_time", "pro_type", "page_type", "isEntity", "store_id", "file_status", "file_money", "approve_time", "approve_name", "if_remove");
                if (mark > 0 && param.fileID > 0)
                {
                    //更新价格
                    if (!string.IsNullOrEmpty(fileLog.listPrice))
                    {
                        //删除原始价格
                        operateContext.bllSession.T_VRGoodDisiPrice.Delete(s => s.file_id == param.fileID);
                        string[] prices = fileLog.listPrice.Split(',');
                        foreach (var item in prices)
                        {
                            string[] price = item.Split(':');
                            int month = Helper.ToInt(price[0]);
                            operateContext.bllSession.T_VRGoodDisiPrice.Add(new T_VRGoodDisiPrice
                            {
                                op_code = Helper.GetGuid,
                                file_id = fileLog.file_id,
                                file_code = fileLog.file_code,
                                price_name = month > 0 ? month.ToString() + "个月价格" : "无限期价格",
                                op_month = month,
                                ori_price = Helper.ToDecimal(price[1])
                            });
                        }
                    }
                }
            }
            else
            {
                //不通过
                var fileCount = operateContext.bllSession.T_DocumentInfo.SelectCount(s => s.file_id == param.fileID && s.file_status == 5);
                int fileStatus = 5;
                if (fileCount <= 0)
                    fileStatus = 6;
                mark = operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { file_status = fileStatus, approve_name = user.user_name, approve_time = DateTime.Now, approve_note = param.approveNote }, s => s.file_id == param.fileID, "file_status", "approve_name", "approve_time", "approve_note");
            }
            if (mark > 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "审核应用商品信息成功！", null);
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Error, "审核应用商品信息失败！", null);
        }
        #endregion

        #region 8.3 ✔获取应用商品详情 + WebApiResultJsonModel GetMetaAppDetail(MetaAppDetailInput param)
        /// <summary>
        ///  8.3 ✔获取应用商品详情
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【323】<br/>
        /// 2、禅道需求 id=【333】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<MetaAppDetailOutput> GetMetaAppDetail(MetaAppDetailInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<MetaAppDetailOutput>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userid);
            var result = operateContext.bllSession.T_DocumentInfoLog.GetMetaAppDetail(param, user_id);
            return ApiResultJsonModel<MetaAppDetailOutput>.RedirectWebApi(WebResultCode.Ok, "成功获取素材商品详情！", result);
        }
        #endregion

        #region 8.4 ✔获取用户已购买的素材列表 + WebApiResultJsonModel GetPaidMaterialList(PayPaidMaterialInput param)
        /// <summary>
        ///  8.4 ✔获取用户已购买的素材列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        public WebApiResultJsonModel<BasePage<PaidMaterialOutput>> GetPaidMaterialList(PayPaidMaterialInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<BasePage<PaidMaterialOutput>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userID);
            var result = operateContext.bllSession.T_VRDDEvent.GetPaidMaterialList(param, user_id);
            return ApiResultJsonModel<BasePage<PaidMaterialOutput>>.RedirectWebApi(WebResultCode.Ok, "成功获取用户已购买的素材列表！", result);
        }
        #endregion

        #region 8.5 ✔获取【奇点元宇宙】素材目录导航 + WebApiResultJsonModel GetQDMaterialTreeData(EmpowerTree model)
        /// <summary>
        ///  8.5 ✔获取【奇点元宇宙】素材目录导航
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        [HCQ2_Common.Attributes.SkipApi]
        public WebApiResultJsonModel<List<QDMaterialTreeOutput>> GetQDMaterialTreeData(QDMaterialTreeInput param)
        {
            if (string.IsNullOrEmpty(param.folderPath) && string.IsNullOrEmpty(param.groupName) && string.IsNullOrEmpty(param.roleCode))
                return ApiResultJsonModel<List<QDMaterialTreeOutput>>.RedirectWebApi(WebResultCode.Exception, "目录path、分组、角色代码三者不能同时为空！", null);
            param.pageType = "QDMaterial";
            var list = operateContext.bllSession.T_DocumentFolder.GetQDMaterialTreeData(param);
            return ApiResultJsonModel<List<QDMaterialTreeOutput>>.RedirectWebApi(WebResultCode.Ok, "获取【奇点元宇宙】素材目录导航成功~", list);
        }
        #endregion

        #region 8.6 ✔获取【元宇宙应用】目录导航 + WebApiResultJsonModel GetQDMetaTreeData(EmpowerTree model)
        /// <summary>
        ///  8.6 ✔获取【元宇宙应用】目录导航
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        [HCQ2_Common.Attributes.SkipApi]
        public WebApiResultJsonModel<List<QDMaterialTreeOutput>> GetQDMetaTreeData(QDMaterialTreeInput param)
        {
            if (string.IsNullOrEmpty(param.folderPath) && string.IsNullOrEmpty(param.groupName) && string.IsNullOrEmpty(param.roleCode))
                return ApiResultJsonModel<List<QDMaterialTreeOutput>>.RedirectWebApi(WebResultCode.Exception, "目录path、分组、角色代码三者不能同时为空！", null);
            param.pageType = "QDMeta";
            var list = operateContext.bllSession.T_DocumentFolder.GetQDMaterialTreeData(param);
            return ApiResultJsonModel<List<QDMaterialTreeOutput>>.RedirectWebApi(WebResultCode.Ok, "获取【奇点元宇宙】素材目录导航成功~", list);
        }
        #endregion

        #region 8.7 ✔获取【元宇宙城市】目录导航 + WebApiResultJsonModel GetQDCityTreeData(EmpowerTree model)
        /// <summary>
        ///  8.7 ✔获取【元宇宙城市】目录导航
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        [HttpPost]
        [HCQ2_Common.Attributes.SkipApi]
        public WebApiResultJsonModel<List<QDCityTreeOutput>> GetQDCityTreeData(QDMaterialTreeInput param)
        {
            if (string.IsNullOrEmpty(param.folderPath) && string.IsNullOrEmpty(param.groupName) && string.IsNullOrEmpty(param.roleCode))
                return ApiResultJsonModel<List<QDCityTreeOutput>>.RedirectWebApi(WebResultCode.Exception, "目录path、分组、角色代码三者不能同时为空！", null);
            param.pageType = "VRBuilding";
            var list = operateContext.bllSession.T_DocumentFolder.GetQDCityTreeData(param);
            return ApiResultJsonModel<List<QDCityTreeOutput>>.RedirectWebApi(WebResultCode.Ok, "获取【元宇宙城市】素材目录导航成功~", list);
        }
        #endregion

        #region 8.8 ✔获取应用版本详情 + WebApiResultJsonModel GetMetaAppVersionDetail (MetaAppVersionInput param)
        /// <summary>
        ///  8.8 ✔获取应用版本详情
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【324】<br/>
        /// 从版本申请历史表中获取最新的版本详情，审核的时候需要获取到这些信息来更新商品表
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<MetaAppVersionOutput> GetMetaAppVersionDetail(MetaAppVersionInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<MetaAppVersionOutput>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var result = operateContext.bllSession.T_DocumentInfoLog.GetMetaAppVersionDetail(param);
            return ApiResultJsonModel<MetaAppVersionOutput>.RedirectWebApi(WebResultCode.Ok, "成功获取应用版本详情！", result);
        }
        #endregion

        #region 8.9 ✔获取应用版本历史列表 + WebApiResultJsonModel GetMetaAppVersionList  (MetaAppVersionListInput param)
        /// <summary>
        ///  8.9 ✔获取应用版本历史列表
        /// </summary>
        /// <param name="param">参数</param>
        /// <returns></returns>
        /// <remarks>
        /// 1、禅道需求 id=【326】<br/>
        /// </remarks>
        [HttpPost]
        public WebApiResultJsonModel<List<MetaAppVersionListOutput>> GetMetaAppVersionList(MetaAppVersionListInput param)
        {
            //1.0 验证数据有效性
            if (!ModelState.IsValid)
                return ApiResultJsonModel<List<MetaAppVersionListOutput>>.RedirectWebApi(WebResultCode.Exception, getErrorMessage(ModelState), null);
            var result = operateContext.bllSession.T_DocumentInfoLog.GetMetaAppVersionList(param);
            return ApiResultJsonModel<List<MetaAppVersionListOutput>>.RedirectWebApi(WebResultCode.Ok, "成功获取应用版本历史列表！", result);
        }
        #endregion

        #region 8.10 ✔判断商品是否已购买 + WebApiResultJsonModel<OutputCheckPurchase> GetPurchaseStatus(InputCheckPurchase param)
        /// <summary>
        /// 8.10 判断商品是否已购买
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        /// <remarks>
        /// 20220621 禅道需求342
        /// 20220622 禅道需求342优化
        /// </remarks>
        [HttpPost]
        [ModelValid]
        public WebApiResultJsonModel<OutputCheckPurchase> GetPurchaseStatus(InputCheckPurchase param)
        {
            //1.1、获取用户id
            int user_id = HCQ2UI_Helper.Session.SysPermissSession.ChangeIdByGuid(param.userid);
            if (user_id <= 0)
                return ApiResultJsonModel<OutputCheckPurchase>.RedirectWebApi(WebResultCode.Exception, "用户信息异常！", null);
            //1.2、获取商品信息
            var file = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == param.fileID && s.file_status == 5);
            if (null == file)
                return ApiResultJsonModel<OutputCheckPurchase>.RedirectWebApi(WebResultCode.Exception, "商品已下架或不存在！", null);
            OutputCheckPurchase obj = new OutputCheckPurchase { attachUrl = file.attach_url };
            //2.1、判断商品创建人是否为自己
            if (file.create_id == user_id)
                obj.status = 0;
            else
            {
                //查询是否有价格
                var priceCount = operateContext.bllSession.T_VRGoodDisiPrice.SelectCount(s => s.file_id == param.fileID && s.ori_price > 0);
                if (priceCount <= 0)
                    obj.status = 1;
                else
                {
                    //2.1.1、价格>0
                    var isPay = operateContext.bllSession.T_DocumentInfo.PayCountByFileId(param.fileID, user_id);
                    obj.status = isPay ? 1 : -1;
                    if (!isPay)
                        obj.attachUrl = string.Empty;
                }
            }
            //2.2、判断是否房间、并且是否购买过
            if (file.page_type.Equals("QDMetaRoom") && obj.status != -1)
            {
                if (file.programId <= 0)
                    return ApiResultJsonModel<OutputCheckPurchase>.RedirectWebApi(WebResultCode.Exception, "当前房间未配置应用id！", null);
                //返回关联的应用商品
                var f = operateContext.bllSession.T_DocumentInfo.FindSingle(s => s.file_id == file.programId);
                if (null != f)
                    obj.attachUrl = f.attach_url;
            }
            return ApiResultJsonModel<OutputCheckPurchase>.RedirectWebApi(WebResultCode.Ok, "判断商品是否已购买成功！", obj);
        }
        #endregion
        #region 9.0 ✔保存自定义封面图地址 + SaveUserHouseImage(InputSaveUserHouseImage param)
        /// <summary>
        ///  9.0 ✔保存自定义封面图地址
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        /// <remarks>
        /// 20221625 禅道346需求
        /// </remarks>
        [HttpPost]
        [ModelValid]
        public WebApiResultJsonModel SaveUserHouseImage(InputSaveUserHouseImage param)
        {
            int userid = SysPermissSession.ChangeIdByGuid(param.userID);
            if (userid <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户编码数据异常！", null);
            var houseInfo = operateContext.bllSession.T_VRStayUserLog.SelectCount(o => o.file_id == param.fileID && o.user_code == param.userID && o.stayType == 1);
            if (houseInfo <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户不是实际入住人,不能修改封面！", null);
            operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { vUrl = param.url }, o => o.file_id == param.fileID, "vUrl");
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "保存成功", null);
        }
        #endregion

        #region 9.1✔ 获取用户住宅详情 + WebApiResultJsonModel<OutputGetUserHouseDetail> GetUserHouseDetail
        /// <summary>
        /// 获取用户住宅详情
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        [ModelValid]
        public WebApiResultJsonModel<OutputGetUserHouseDetail> GetUserHouseDetail(InputGetUserHouseDetail param)
        {
            OutputGetUserHouseDetail houseDetail = operateContext.bllSession.T_VRStayUserLog.GetUserHouseDetail(param);
            return ApiResultJsonModel<OutputGetUserHouseDetail>.RedirectWebApi(WebResultCode.Ok, "获取成功", houseDetail);
        }
        #endregion

        #region 9.2✔ 保存用户住宅别名 + WebApiResultJsonModel<int?> SaveUserHouseAlias(InputSaveUserHouseAlias param)
        /// <summary>
        /// 保存用户住宅别名
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [HttpPost]
        [ModelValid]
        public WebApiResultJsonModel SaveUserHouseAlias(InputSaveUserHouseAlias param)
        {
            int userid = SysPermissSession.ChangeIdByGuid(param.userID);
            if (userid <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户编码数据异常！", null);
            var houseInfo = operateContext.bllSession.T_VRStayUserLog.SelectCount(o => o.file_id == param.fileID && o.user_code == param.userID && o.stayType == 1);
            if (houseInfo <= 0)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "用户不是实际入住人,不能修改别名！", null);
            //有值不能超过10个字符
            if (!string.IsNullOrEmpty(param.alias) && param.alias.Length > 10)
                return ApiResultJsonModel.RedirectWebApi(WebResultCode.Exception, "别名最多允许10个中文字或20个半角英文字符！", null);
            operateContext.bllSession.T_DocumentInfo.Modify(new T_DocumentInfo { alias_name = param.alias }, o => o.file_id == param.fileID, "alias_name");
            return ApiResultJsonModel.RedirectWebApi(WebResultCode.Ok, "保存成功", null);
        }
        #endregion

        #region 9.3 ✔ 获取住宅详情 + GetHouseDetail(InputGetHouseDetail param)
        /// <summary>
        /// 9.3 ✔ 获取住宅详情
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        /// <remarks>
        /// 20220703元宇宙需求2.1
        /// </remarks>
        [HttpPost]
        [ModelValid]
        public WebApiResultJsonModel<OutputGetHouseDetail> GetHouseDetail(InputGetHouseDetail param)
        {
            OutputGetHouseDetail list = operateContext.bllSession.T_VRStayUserLog.GetHouseDetail(param);
            return ApiResultJsonModel<OutputGetHouseDetail>.RedirectWebApi(WebResultCode.Ok, "", list);
        }
        #endregion
    }
}